Skip to content

docs: HTTPS outcalls guide#10

Merged
marc0olo merged 6 commits into
mainfrom
docs/guides-backends-https-outcalls
Mar 16, 2026
Merged

docs: HTTPS outcalls guide#10
marc0olo merged 6 commits into
mainfrom
docs/guides-backends-https-outcalls

Conversation

@raymondk
Copy link
Copy Markdown
Collaborator

@raymondk raymondk commented Mar 13, 2026

Summary

How-to guide for making HTTPS outcalls from canisters. Covers:

  • How HTTPS outcalls work (replica consensus, transform functions, 2MB response limit)
  • GET request examples in both Motoko and Rust with complete, copy-pasteable code
  • POST request pattern with idempotency keys and body-stripping transform
  • Transform function debugging (no-consensus errors, JSON normalization)
  • Cycle cost estimation (formula, CDK auto-attach, max_response_bytes impact)
  • Limitations and pitfalls (public endpoints only, Host header, timeout, flexible outcalls future)
  • Local testing with icp-cli (single-node consensus caveat)
  • Links to exchange-rate canister (XRC) as production example, send_http_get/post examples, and concept page

Sync recommendation

Informed by dfinity/portaldocs/building-apps/network-features/using-http/https-outcalls/, verified against .sources/cdk-rs (ic-cdk 0.19) and .sources/icskills/skills/https-outcalls/

Copy link
Copy Markdown
Member

@marc0olo marc0olo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the spelling mistake and also inform the dev about potential local oversight of the need for the transform function because locally you only run the call on a single replica. Locally you will always have consensus on the responses.

Comment thread docs/guides/backends/https-outcalls.md Outdated
@marc0olo
Copy link
Copy Markdown
Member

Feedback addressed:

  • Fixed "off-chain" → "offchain" per project spelling convention (line 9)

@marc0olo
Copy link
Copy Markdown
Member

Feedback addressed:

  • Added note in "Testing locally" section about single-node consensus: transform functions aren't exercised locally, developers should verify transforms handle varying inputs before deploying to multi-node subnets

@marc0olo
Copy link
Copy Markdown
Member

Feedback addressed:

  • Fixed "Both GET, HEAD, and POST" → "The GET, HEAD, and POST" (grammar)
  • Removed unused serde_json from Cargo.toml dependencies
  • Added Rust function name hint (get_icp_price) to testing section CLI example

@marc0olo
Copy link
Copy Markdown
Member

Review: HTTPS Outcalls

Must fix

  • Missing exchange-rates example link: The content brief explicitly says "Link to the exchange-rates example for a complete real-world use case." The page links to send_http_get and send_http_post but omits the exchange-rates example, which demonstrates a real production pattern (multi-canister, periodic data fetching). Add it — it's the most valuable example for developers building real applications.

  • Response size limit (2MB) not called out prominently: The content brief says "Cover... response size limits." The page only mentions this indirectly in the cycle costs section ("assumes 2MB"). The 2MB hard limit is a common surprise for developers — it deserves its own sentence or bullet, e.g., "The maximum response body is 2MB (2,097,152 bytes). Requests exceeding this limit fail." The icskill lists this as mistake docs: application architecture concept page #4 that breaks builds.

  • POST example snippet is not self-contained: The Motoko POST snippet uses Blob, Text, IC, and Call without imports, and transformPost/postData appear outside any actor. A reader copying this snippet gets a compile error. Either wrap it in a full actor with imports (like the GET example) or add a note like "Add these methods inside the actor from the GET example above."

Suggestions

  • No Rust POST example: The POST section only shows Motoko. The GET section has both Rust and Motoko. For consistency and because Rust is the more common IC language, consider adding a Rust POST snippet or at minimum linking to the Rust send_http_post example and the Motoko send_http_post example (currently only links to the Rust version).

  • HEAD method not mentioned in body: The intro says "The GET, HEAD, and POST methods are supported" but HEAD is never shown or discussed. Either drop it from the intro or add a one-liner explaining when HEAD is useful (e.g., checking if a resource exists without downloading the body).

  • "Host" header pitfall omitted: The icskill lists "Forgetting the Host header" as a common mistake — some API endpoints require it explicitly. Worth a one-line note in the transform or GET section.

  • Localhost/private IP restriction not mentioned: The icskill notes that HTTPS outcalls can only reach public internet endpoints — localhost, 10.x.x.x, 192.168.x.x are blocked. This is a common gotcha for developers testing against local services.

  • is_replicated field unexplained: Both code examples set is_replicated = null/None without explaining what it does. Either drop it (since None is the default) or add a brief comment explaining it controls whether the outcall goes through consensus.

Verified

  • All internal links resolve: ../../reference/management-canister.md, ../../concepts/https-outcalls.md, ../chain-fusion/ethereum.md, ../../reference/cycles-costs.md all exist
  • External URLs verified: github.com/dfinity/examples/tree/master/rust/send_http_get, motoko/send_http_get, rust/send_http_post all match .sources/examples/
  • CLI commands verified against .sources/icp-cli/docs/reference/cli.md: icp network start -d, icp deploy backend, icp canister call are all valid
  • No dfx references — clean
  • No .mdx/JSX — plain markdown throughout
  • Motoko uses mo:core/ (not mo:base/) per content rules
  • Rust imports and API patterns (ic_cdk::management_canister::http_request, TransformArgs, TransformContext, TransformFunc) match icskill and .sources/examples/
  • Call.httpRequest (Motoko auto-cycle-attachment) verified against icskill
  • Cycle cost formula matches icskill reference (49M base, 5200/request byte, 10400/response byte on 13-node subnet)
  • Frontmatter complete and consistent with body
  • Sync recommendation present
  • Previous feedback (offchain spelling, local testing note, grammar fix, unused serde_json removal) appears addressed per PR comments

- Add 2MB response limit as prominent bullet in "How HTTPS outcalls work"
- Add note that POST snippet goes inside the GET actor (self-contained)
- Add both Rust and Motoko links for send_http_post example
- Add HEAD method explanation in intro
- Add "Limitations and pitfalls" section (public endpoints only, Host header, timeout)
- Add non-replicated (flexible) outcalls future-work note
- Remove is_replicated from code examples (None is the default)
- Add Exchange Rate Canister (XRC) as production example in "What's next"
@marc0olo
Copy link
Copy Markdown
Member

Feedback addressed:

Must-fix:

  • Added 2MB response limit as prominent bullet (docs: network overview concept page #3) in "How HTTPS outcalls work" section
  • Added note that Motoko POST snippet goes inside the GET actor above (self-contained context)
  • Added Exchange Rate Canister (XRC) link in "What's next" as a production service powered by HTTPS outcalls

Suggestions:

  • Added both Rust and Motoko links for send_http_post example
  • Added HEAD method explanation in the intro paragraph
  • Added "Limitations and pitfalls" section: public endpoints only, Host header requirement, ~30s timeout
  • Added non-replicated (flexible) outcalls note as future work (tracks portal#5890)
  • Removed is_replicated from code examples (None is the default; avoids unexplained field)

Non-replicated outcalls (is_replicated=false) already exist as experimental.
Flexible outcalls with dedicated pricing are what's under development.
@marc0olo marc0olo merged commit dfb9264 into main Mar 16, 2026
1 check passed
@marc0olo marc0olo deleted the docs/guides-backends-https-outcalls branch March 16, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants